import 'package:flutter/material.dart';

enum ButtonType {
  DEFAULT,
  PRIMARY,
  SUCCESS,
  INFO,
  WARN,
  DANGER;
}

/// 自定义封装的按钮组件，具备统一的 UI 效果
///
/// > 默认组件构造方式：
/// ```dart
/// Button(
///   text: String!,
///   style: TextStyle?,
///   margin: EdgeInsets?,
///   padding: EdgeInsets?,
///   icon: Widget?,
///   border: Border?,
///   radius: BorderRadius?,
///   onTap: VoidCallback?, // () => {}
/// );
/// ```
/// > 不同的按钮类型：
/// ```dart
/// Button.primary(...); // 主要按钮
/// Button.success(...); // 成功按钮
/// Button.info(...);    // 信息提示按钮
/// Button.warn(...);    // 警告类型按钮
/// Button.danger(...);  // 危险按钮，主要用于一些删除场景
/// ```
class Button extends StatefulWidget {
  final String? text;
  final Widget? child;
  final TextStyle? style;
  final EdgeInsets? margin;
  final EdgeInsets? padding;
  final Widget? icon;
  final Border? border;
  final BorderRadius? radius;
  final VoidCallback? onTap;
  final ButtonType type;

  const Button({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.DEFAULT,
        assert(text != null || child != null);

  const Button.primary({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.PRIMARY,
        assert(text != null || child != null);

  const Button.success({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.SUCCESS,
        assert(text != null || child != null);

  const Button.info({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.INFO,
        assert(text != null || child != null);

  const Button.warn({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.WARN,
        assert(text != null || child != null);

  const Button.danger({
    super.key,
    this.text,
    this.child,
    this.style,
    this.margin,
    this.padding,
    this.icon,
    this.border,
    this.radius,
    this.onTap,
  })  : type = ButtonType.DANGER,
        assert(text != null || child != null);

  @override
  State<StatefulWidget> createState() => _ButtonState();
}

class _ButtonState extends State<Button> {
  Color? _bgColor;
  Color? _textColor;

  @override
  void initState() {
    super.initState();
    _switchStyle(active: false);
  }

  @override
  void didUpdateWidget(Button oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.type != widget.type) {
      _switchStyle(active: false);
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _switchStyle(active: false);
  }

  @override
  Widget build(BuildContext context) {
    Widget body = widget.child ??
        DefaultTextStyle(
          style: TextStyle(color: _textColor),
          child: Text(widget.text!, style: widget.style),
        );

    if (widget.icon != null) {
      body = Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          IconTheme(
            data: IconThemeData(color: _textColor),
            child: widget.icon!,
          ),
          const SizedBox(width: 5),
          body
        ],
      );
    }

    // 按钮的装饰样式
    BoxDecoration decoration = BoxDecoration(
      border: widget.border,
      boxShadow: [
        BoxShadow(
          color: _bgColor!.withAlpha(80),
          blurRadius: 6,
          offset: const Offset(0, 5),
          spreadRadius: 1,
        ),
      ],
      borderRadius:
      widget.radius ?? const BorderRadius.all(Radius.circular(100)),
      color: _bgColor,
    );

    // 按钮的容器
    body = Container(
      decoration: decoration,
      padding: widget.padding ??
          const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
      margin: widget.margin,
      child: body,
    );

    // 监听点击事件
    return GestureDetector(
      onTapDown: (e) => _switchStyle(active: true),
      onTapUp: (e) => _resetStyle(),
      onTapCancel: _resetStyle,
      child: body,
    );
  }

  /// 重置按钮样式
  void _resetStyle() {
    Future.delayed(const Duration(milliseconds: 100), () {
      _switchStyle(active: false);
      widget.onTap?.call();
    });
  }

  /// 根据类型不同选择样式
  void _switchStyle({required bool active}) {
    super.setState(() {
      switch (widget.type) {
        case ButtonType.DEFAULT:
          _bgColor = active ? Colors.grey[800] : Colors.grey[900];
          _textColor = Colors.white;
          break;
        case ButtonType.PRIMARY:
          _bgColor = active ? Colors.blueAccent[400] : Colors.blueAccent[700];
          _textColor = Colors.white;
          break;
        case ButtonType.SUCCESS:
          _bgColor = active ? Colors.greenAccent[400] : Colors.greenAccent[700];
          _textColor = Colors.white;
          break;
        case ButtonType.INFO:
          _bgColor = active ? Colors.cyan[800] : Colors.cyan[900];
          _textColor = Colors.white;
          break;
        case ButtonType.WARN:
          _bgColor = active ? Colors.yellow[800] : Colors.yellow[900];
          _textColor = Colors.white;
          break;
        case ButtonType.DANGER:
          _bgColor = active ? Colors.redAccent : Colors.redAccent[400];
          _textColor = Colors.white;
          break;
      }
    });
  }
}